package com.soul.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.soul.common.bean.vo.BaseDataVo;
import com.soul.common.exception.BaseException;
import com.soul.common.service.BaseDataService;
import com.soul.common.utils.ListUtil;
import com.soul.doc.bean.dto.SingerAddDto;
import com.soul.doc.bean.dto.SingerSearchDto;
import com.soul.doc.bean.dto.SingerUpdateDto;
import com.soul.doc.bean.po.SingerPo;
import com.soul.common.bean.vo.FileVo;
import com.soul.doc.bean.vo.SingerVo;
import com.soul.doc.mapper.SingerMapper;
import com.soul.doc.service.FileService;
import com.soul.doc.service.SingerService;
import com.soul.common.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sws
 * @since 2023-11-19 11:05:21
 */
@Service
public class SingerServiceImpl extends BaseService<SingerMapper, SingerPo> implements SingerService {

    @Autowired
    private FileService fileService;
    @Autowired
    private BaseDataService baseDataService;
    @Override
    public IPage<SingerVo> querySingerList(Integer page, Integer size, SingerSearchDto searchDto){
        LambdaQueryWrapper<SingerPo> wrapper = this.lambadaQueryWrapper();
        if (ObjectUtil.isNotEmpty(searchDto)){
            wrapper.like(ObjectUtil.isNotEmpty(searchDto.getName()),SingerPo::getName,searchDto.getName())
                    .eq(ObjectUtil.isNotEmpty(searchDto.getType()) && !ObjectUtil.equals(searchDto.getType(),"0"),SingerPo::getType,searchDto.getType())
                    .eq(ObjectUtil.isNotEmpty(searchDto.getArea()) && !ObjectUtil.equals(searchDto.getArea(),"0"),SingerPo::getArea,searchDto.getArea())
                    .orderByAsc(SingerPo::getSort);
        }
        Page<SingerPo> userPoPage = this.page(new Page<>(page, size), wrapper);
        BaseDataVo baseDataVo = baseDataService.loadBaseData(userPoPage.getRecords(), (t, b) -> {
            b.addDictType("singer.type");
            b.addDictType("singer.area");
            b.addFileId(t.getPicFileId());
        });
        IPage<SingerVo> convert = userPoPage.convert(t->this.toDataVo(t,baseDataVo));
        return convert;
    }

    private SingerVo toDataVo(SingerPo po){
        BaseDataVo baseDataVo = new BaseDataVo();
        baseDataVo.addDictType("singer.type");
        baseDataVo.addDictType("singer.area");
        baseDataVo.addFileId(po.getPicFileId());
        baseDataService.loadBaseData(baseDataVo);
        return toDataVo(po,baseDataVo);
    }


    private SingerVo toDataVo(SingerPo po, BaseDataVo baseDataVo){
        //Male, female, combined
        SingerVo singerVo = BeanUtil.copyProperties(po, SingerVo.class);
        singerVo.setTypeVo(baseDataVo.getDictVo("singer.type",po.getType()));
        singerVo.setAreaVo(baseDataVo.getDictVo("singer.area",po.getArea()));
        FileVo fileVo = baseDataVo.getFileVo(po.getPicFileId());
        if (ObjectUtil.isNotEmpty(fileVo)){
            singerVo.setPicFileVo(fileVo);
            singerVo.setPicUrl(fileVo.getUrl());
        }
        return singerVo;
    }


    private List<SingerVo> toDataListVo(List<SingerPo> pos){
        if (ObjectUtil.isNotEmpty(pos)){
            BaseDataVo baseDataVo = baseDataService.loadBaseData(pos, (t, b) -> {
                b.addDictType("singer.type");
                b.addDictType("singer.area");
                b.addFileId(t.getPicFileId());
            });
            return ListUtil.toValueList(pos, t -> this.toDataVo(t, baseDataVo));
        }
        return new ArrayList<>();
    }


    @Override
    public void addSinger(SingerAddDto addDto){
        SingerPo singerPo = BeanUtil.copyProperties(addDto, SingerPo.class);
        Long maxSort = this.getMaxSort();
        singerPo.setSort(maxSort);
        this.save(singerPo);
    }

    @Override
    public void updateSinger(SingerUpdateDto updateDto){
        SingerPo singerPo = this.getById(updateDto.getId());
        if (ObjectUtil.isEmpty(singerPo)) {
            throw new BaseException("数据不存在！");
        }
        BeanUtil.copyProperties(updateDto,singerPo);
        this.updateById(singerPo);
    }

    @Override
    public void deleteSinger(List<Long> ids){
        this.removeBatchByIds(ids);
    }

    @Override
    public SingerVo getSinger(Long id){
        SingerPo singerPo = this.getById(id);
        return toDataVo(singerPo);
    }

    @Override
    public List<SingerVo> querySingerListAll() {
        List<SingerPo> list = this.list();
        return ListUtil.toValueList(list, this::toDataVo);
    }

    @Override
    public List<SingerVo> getSingerVosByIds(Collection<Long> singerIds){
        List<SingerPo> singerPos = this.listByIds(singerIds);
        return this.toDataListVo(singerPos);
    }


    @Override
    public IPage<SingerVo> queryHotSingerList(Integer page, Integer size, SingerSearchDto searchDto){
        Page<SingerVo> objectPage = new Page<>(page, size);
        IPage<SingerVo> singerVoIPage = this.mapper.selectHotSingerList(objectPage, searchDto);
        List<SingerVo> records = singerVoIPage.getRecords();
        BaseDataVo baseDataVo = baseDataService.loadBaseData(records, (t, b) -> {
            b.addFileId(t.getPicFileId());
        });
        for (SingerVo record : records) {
            FileVo fileVo = baseDataVo.getFileVo(record.getPicFileId());
            record.setPicFileVo(fileVo);
            if (ObjectUtil.isNotEmpty(fileVo)) {
                record.setPicUrl(fileVo.getUrl());
            }
        }
        return singerVoIPage;
    }

    @Override
    public List<Long> getSingerIdsByKeyWord(String name){

        List<SingerPo> pos = this.getLambadaQueryWrapper().like(SingerPo::getName, name).or().like(SingerPo::getEngName, name).list();
        return ListUtil.toValueList(pos,SingerPo::getId);
    }
}
